package com.dure.hotmemory.scenes.dzxl;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.EmbossMaskFilter;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.os.Build;
import android.text.TextUtils;

import com.dure.commonlib.util.AssetsUtil;
import com.dure.commonlib.util.PreferencesUtils;
import com.dure.hotmemory.R;
import com.dure.hotmemory.bean.Cell;
import com.dure.hotmemory.bean.Code;
import com.dure.hotmemory.drawview.BaseSurfaceView;
import com.dure.hotmemory.scenes.BaseScene;
import com.socks.library.KLog;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * Created by dure on 2017/6/8.
 * 编码练习
 */

public class BMXLScene extends BaseScene {
    private List<Code> codeList = new ArrayList<>();
    private List<Code> subCodeList = new ArrayList<>();
    private ArrayList<Integer> randomOptionIndex = new ArrayList<>();
    Paint paint;
    private int startIndex, endIndex, currentIndex;
    private boolean showNext = true;
    private Bitmap currentBitmap;
    private String currentName;
    private int bitmapWidth, bitmapHeight;
    private Rect srcRect;
    private long startTime;
    private boolean dataPrepared;
    private Map<Code, List<Integer>> typeMap = new HashMap<>();// 用于保存展示过的形式, list里面0=图片,1=数字,2=文字
    private Code currentShowingCode;
    private int currentShowingType;
    private int currentShowingIndex;
    private int totalShowNumber;
    private RectF frameRectF = new RectF();
    private ArrayList<Cell> optionCellList = new ArrayList<>();
    private Cell selectedCell;
    private long selectedStartTime, changeTime;
    private int optionShowingType;
    private RectF rightBtnRectF, leftBtnRectF;
    private int correctNumber;
    private String finishInfo;
    private boolean trainingFinished;
    private boolean restart = true;
    int typeCount;
    String alias;
    private EmbossMaskFilter emboss;
    int[] colors = {Color.WHITE, Color.parseColor("#00BDFF")};

    public BMXLScene(BaseSurfaceView baseSurfaceView) {
        super(baseSurfaceView);
        left = getViewWidth();
        paint = new Paint();
        paint.setAntiAlias(true);
        alias = PreferencesUtils.getString(activity, "current_alias");
        currentIndex = startIndex = PreferencesUtils.getInt(activity, alias + ":start_index", 0);
        endIndex = PreferencesUtils.getInt(activity, alias + ":end_index", 9);
        totalShowNumber = endIndex - startIndex + 1;
        changeTime = (long) (PreferencesUtils.getFloat(activity, alias + ":change_time", 1) * 1000);

        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N_MR1) {
            float[] direction = new float[] { 1, 1, 1 };
            // 设置环境光亮度
            float light = 0.5f;
            // 选择要应用的反射等级
            float specular = 10;// 这个参数更改没有看出效果上面的变化
            // 向mask应用一定级别的模糊
            float blur = 3;// 这个参数可以控制立体侧面的宽度
            emboss = new EmbossMaskFilter(direction, light, specular, blur);
            paint.setMaskFilter(emboss);
        }

        if (TextUtils.equals(alias, "pk")) {
            typeCount = 2;
        } else {
            typeCount = 3;
        }
        dataInited = true;
    }

    public void setCodeList(List<Code> codeList) {
        if (codeList != null && codeList.size() > 0) {
            this.codeList.clear();
            this.codeList.addAll(codeList);

        }
    }

    @Override
    public void handleData() {
        if (!dataInited) {
            return;
        }
        if (codeList.size() == 0) {
            return;
        }
        if (restart) {
            restart = false;
            subCodeList = new ArrayList<>(Arrays.asList(new Code[totalShowNumber]));
            KLog.d("lesleixz","currentIndex = " + currentIndex);
            KLog.d("lesleixz","endIndex = " + endIndex);
            KLog.d("lesleixz","codeList size = " + codeList.size());
            KLog.d("lesleixz","alias = " + alias);
            Collections.copy(subCodeList, codeList.subList(currentIndex, endIndex + 1));
//            subCodeList = codeList.subList(currentIndex, endIndex + 1).clone();
            correctNumber = 0;
        }
        if (showNext) {
            showNext = false;

            currentShowingCode = getCurrentShow();
            currentShowingIndex = codeList.indexOf(currentShowingCode);

            randomOptionIndex = getRandomImagesIndex(8, totalShowNumber);

            // 判断randomOptionIndex里面是否含有当前要选择的图片， 没有则加进去
            if (!randomOptionIndex.contains(currentShowingIndex)) {
                int randomReplaceIndex = (int) (Math.random() * randomOptionIndex.size());
                randomOptionIndex.remove(randomReplaceIndex);
                randomOptionIndex.add(randomReplaceIndex, currentShowingIndex);
            }

            optionCellList = getCellList();
            startTime = System.currentTimeMillis();
            dataPrepared = true;
        }

        checkSelection();

    }

    private void checkSelection() {
        if (selectedCell != null) {
            // 获取当前需要被选择的卡片名称
            if (TextUtils.equals(selectedCell.code.name, currentShowingCode.name)) {
                selectedCell.color = Color.GREEN;
                selectedCell.isCorrect = true;
            } else {
                selectedCell.color = Color.RED;
                selectedCell.isCorrect = false;

            }
            // 停顿1秒后切换下一张待选卡片
            if (System.currentTimeMillis() - selectedStartTime > changeTime) {
                selectedStartTime = System.currentTimeMillis();
                selectedCell.color = Color.WHITE;
                selectedCell.selected = false;
                if (!selectedCell.isCorrect) {
                    showNext = true;
                } else {// 选择正确
                    correctNumber++;
                    currentShowingCode.showTimes++;
//                    if (TextUtils.equals(alias, "数字") && currentShowingCode.showTimes == 3) {
//                        subCodeList.remove(currentShowingCode);
//                    } else
                    if (currentShowingCode.showTimes == typeCount) {
                        subCodeList.remove(currentShowingCode);
                    }

                    if (subCodeList.size() == 0) {
                        finishInfo = "恭喜你完成训练！";
                        trainingFinished = true;
                    } else {
                        showNext = true;
                    }

                }

                selectedCell.isCorrect = false;
                selectedCell = null;

            }
        }
    }

    private Code getCurrentShow() {
        int showingIndex = (int) (Math.random() * subCodeList.size());
        Code showingCode = subCodeList.get(showingIndex);
        if (showingCode.showTimes == 0) {
            showingCode.showType = (int) (Math.random() * typeCount);
        } else {
            showingCode.showType = (showingCode.showType + 1) % typeCount;
        }


        return showingCode;
    }

    private ArrayList<Integer> getRandomImagesIndex(int showNumber, int totalNumber) {
        ArrayList<Integer> indexList = new ArrayList<>();
        for (int i = 0; i < showNumber; i++) {
            int randomNum = (int) (Math.random() * totalNumber);

            while (indexList.contains(randomNum + startIndex)) {
                randomNum = (int) (Math.random() * totalNumber);
            }

            indexList.add(randomNum + startIndex);

        }

        return indexList;
    }

    private ArrayList<Cell> getCellList() {
        ArrayList<Cell> cellList = new ArrayList<>();

//        float padding = baseSurfaceView.getWidth() * 0.2f / 5;
//        float frameSize = baseSurfaceView.getWidth() * 0.8f;
//        float perImageSize = frameSize / 4;
//
//        float frameTop = baseSurfaceView.getHeight() - baseSurfaceView.getWidth() / 2;
//        frameRectF = new RectF(padding, frameTop, baseSurfaceView.getWidth() - padding, frameTop + frameSize + 2 * padding);

        int spanIndex = (int) (Math.random() * (typeCount - 1)) + 1;
        optionShowingType = (currentShowingCode.showType + spanIndex) % typeCount;

        float frameSize = baseSurfaceView.getWidth();
        float frameHeight;
        float perImageSize = frameSize * 0.8f / 4;
        float perImageHeight;
        float padding = frameSize * 0.2f / 5;

        float frameLeft = padding;
        float frameTop;
        if (TextUtils.equals(alias, "pk") && optionShowingType == 0) {
            frameHeight = frameSize * 1.5f;
            perImageHeight = perImageSize * 1.5f;
            frameTop = baseSurfaceView.getHeight() - frameHeight / 2 + padding;
        } else {
            frameHeight = frameSize;
            perImageHeight = perImageSize;
            frameTop = baseSurfaceView.getHeight() - baseSurfaceView.getWidth() / 2;
        }


        float frameRight = baseSurfaceView.getWidth() - padding;
        float frameBottom = baseSurfaceView.getHeight() - padding;
        frameRectF = new RectF(frameLeft, frameTop, frameRight, frameBottom);


        for (int i = 0; i < randomOptionIndex.size(); i++) {
            int row = i / 4;
            int column = i % 4;
            float dstLeft = padding * (column + 1) + column * perImageSize;
            float dstTop = padding * (row + 1) + row * perImageHeight + frameTop;
            float dstRight = dstLeft + perImageSize;
            float dstBottom = dstTop + perImageHeight;

            Code code = codeList.get(randomOptionIndex.get(i));

            RectF dstRect = new RectF(dstLeft, dstTop, dstRight, dstBottom);

            Cell cell = new Cell();
            cell.index = i;
            cell.code = code;
            cell.rectF = dstRect;
            cell.color = Color.WHITE;

            cellList.add(cell);
        }

        return cellList;
    }

    @Override
    public void handleDraw(Canvas canvas) {
        if (!dataInited) {
            return;
        }
        if (codeList.size() == 0) {
            return;
        }

        if (!dataPrepared) {
            return;
        }

        drawCenterView(canvas);
        drawSelectingOptions(canvas);
        drawScore(canvas);

        if (trainingFinished) {
            drawFinishDialog(canvas);
        }
    }

    private void drawCenterView(Canvas canvas) {
        int centerX = canvas.getWidth() / 2;
        int centerY = canvas.getHeight() / 2;

        RectF dstRect;
        if (TextUtils.equals(alias, "pk") && currentShowingCode.showType == 0) {
            Bitmap bitmap = getBitmap(currentShowingCode);
//            Bitmap bitmap = BitmapFactory.decodeStream(AssetsUtil.getAssets(activity, currentShowingCode.image));

            int dstLeft = centerX - bitmap.getWidth() / 2;
            float dstTop = centerY - bitmap.getHeight() / 1.2f;
            int dstRight = centerX + bitmap.getWidth() / 2;
            float dstBottom = dstTop + (dstRight - dstLeft) * 1.5f;
            dstRect = new RectF(dstLeft, dstTop, dstRight, dstBottom);
        } else {
            int dstWidth = (int) (canvas.getWidth() * 0.5f);
            int imageLeft = centerX - dstWidth / 2;
            float imageTop = centerY - dstWidth / 1.2f;
            int imageRight = centerX + dstWidth / 2;
            float imageBottom = imageTop + dstWidth;
            dstRect = new RectF(imageLeft, imageTop, imageRight, imageBottom);
        }


        float arc = dstRect.width() / 15;
        paint.setColor(Color.WHITE);
        canvas.drawRoundRect(dstRect, arc, arc, paint);

        drawByShowingType(canvas, currentShowingCode, currentShowingCode.showType, dstRect, centerX, dstRect.top + dstRect.height() / 2);


    }

    private void drawSelectingOptions(Canvas canvas) {

        for (int i = 0; i < optionCellList.size(); i++) {
            Cell cell = optionCellList.get(i);

            paint.setColor(cell.color);
            float arc = cell.rectF.width() / 10;
            canvas.drawRoundRect(cell.rectF, arc, arc, paint);

            float cellCenterX = cell.rectF.left + cell.rectF.width() / 2;
            float cellCenterY = cell.rectF.top + cell.rectF.height() / 2;

            drawByShowingType(canvas, cell.code, optionShowingType, cell.rectF, cellCenterX, cellCenterY);
        }
    }

    private void drawByShowingType(Canvas canvas, Code code, int showType, RectF dstRect, float centerX, float centerY) {
        if (showType == 0) {

//            Bitmap bitmap = BitmapFactory.decodeStream(AssetsUtil.getAssets(context, code.image));
            Bitmap bitmap = getBitmap(code);
            Rect srcRect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
            float padding = dstRect.width() * 0.1f;
            float dstLeft = dstRect.left + padding;
            float dstTop = dstRect.top + padding;
            float dstRight = dstRect.right - padding;
            float dstBottom = dstRect.bottom - padding;
            RectF newDstRect = new RectF(dstLeft, dstTop, dstRight, dstBottom);
            canvas.drawBitmap(bitmap, srcRect, newDstRect, null);
        } else if (showType == 1) {
            String numberStr = code.number;
            float showingSize = dstRect.width();
            float wordsSize;
            if (numberStr.length() <= 2) {
                wordsSize = showingSize * 0.8f / 2;
            } else {
                wordsSize = showingSize * 0.8f / numberStr.length();
            }
            paint.setTextSize(wordsSize);
            float wordsWidth = paint.measureText(numberStr);
            float wordsLeft = centerX - wordsWidth / 2;
            float wordsBottom = centerY + wordsSize / 3;
            paint.setColor(Color.parseColor("#00BDFF"));
            canvas.drawText(numberStr, wordsLeft, wordsBottom, paint);
        } else if (showType == 2) {
            String nameStr = code.name;
            float showingSize = dstRect.width();
            float wordsSize;
            if (nameStr.length() <= 2) {
                wordsSize = showingSize * 0.8f / 2;
            } else {
                wordsSize = showingSize * 0.8f / nameStr.length();
            }
            paint.setTextSize(wordsSize);
            float wordsWidth = paint.measureText(nameStr);
            float wordsLeft = centerX - wordsWidth / 2;
            float wordsBottom = centerY + wordsSize / 3;
            paint.setColor(Color.parseColor("#00BDFF"));
            canvas.drawText(nameStr, wordsLeft, wordsBottom, paint);
        }
    }

    private void drawScore(Canvas canvas) {
        String scoreStr = String.format("完成进度: %.2f%%", correctNumber * 1f / (totalShowNumber * typeCount) * 100);

        float textSize = canvas.getWidth() * 0.06f;
        paint.setTextSize(textSize);
        float contentWidth = paint.measureText(scoreStr);

        float rightPadding = canvas.getWidth() * 0.05f;
        float topPadding = rightPadding;

        float contentLeft = canvas.getWidth() - rightPadding - contentWidth;
        float contentBottom = topPadding + textSize;

        paint.setColor(Color.WHITE);
        canvas.drawText(scoreStr, contentLeft, contentBottom, paint);
    }

    private void drawFinishDialog(Canvas canvas) {
        String infoStr = finishInfo;
        String exitStr = "关闭";

        float dialogWidth = canvas.getWidth() * 0.8f;
        float dialogHeight = dialogWidth * 0.6f;
        float infoPartHeight = dialogHeight * 0.7f;
        float btnPartHeight = dialogHeight * 0.3f;

        float infoTextSize = dialogWidth * 0.8f / infoStr.length();

        // 绘制dialog frame
        float dialogLeft = canvas.getWidth() / 2 - dialogWidth / 2;
        float dialogTop = canvas.getHeight() / 2 - dialogHeight / 2;
        float dialogRight = canvas.getWidth() / 2 + dialogWidth / 2;
        float dialogBottom = canvas.getHeight() / 2 + dialogHeight / 2;
        RectF dialogRectF = new RectF(dialogLeft, dialogTop, dialogRight, dialogBottom);
        paint.setColor(Color.WHITE);
        float arc = dialogRectF.width() / 15;

        LinearGradient lg = new LinearGradient(dialogRectF.width() /2, 0, dialogRectF.width() /2, dialogRectF.height(), colors, null, Shader.TileMode.MIRROR);
        paint.setShader(lg);
        canvas.drawRoundRect(dialogRectF, arc, arc, paint);
        paint.setShader(null);

        // 绘制info
        paint.setTextSize(infoTextSize);
        float infoWidth = paint.measureText(infoStr);
        float infoLeft = canvas.getWidth() / 2 - infoWidth / 2;
        float infoBottom = dialogTop + infoPartHeight / 2 + infoTextSize / 2;
        paint.setColor(Color.RED);
        canvas.drawText(infoStr, infoLeft, infoBottom, paint);

        float btnWidth = dialogWidth * 0.3f;
        float btnHeight = btnWidth / 2.5f;
        float btnTextSize = btnHeight * 0.6f;

        // 绘制中间btn
        float leftBtnLeft = canvas.getWidth() / 2 - btnWidth / 2;
        float leftBtnBottom = dialogBottom - btnPartHeight / 2 + btnHeight / 2;
        float leftBtnRight = leftBtnLeft + btnWidth;
        float leftBtnTop = leftBtnBottom - btnHeight;
        leftBtnRectF = new RectF(leftBtnLeft, leftBtnTop, leftBtnRight, leftBtnBottom);
        arc = leftBtnRectF.width() / 15;
        paint.setColor(Color.parseColor("#00BDFF"));
        canvas.drawRoundRect(leftBtnRectF, arc, arc, paint);

        paint.setTextSize(btnTextSize);
        float exitStrWidth = paint.measureText(exitStr);
        float exitLeft = leftBtnLeft + btnWidth / 2 - exitStrWidth / 2;
        float exitBottom = leftBtnBottom - btnHeight * 0.3f;
        paint.setColor(Color.WHITE);
        canvas.drawText(exitStr, exitLeft, exitBottom, paint);


    }

    private Bitmap getBitmap(Code code){
        Bitmap bitmap = null;
        if (!code.isCreated)
            bitmap = BitmapFactory.decodeStream(AssetsUtil.getAssets(context, code.image));
        else{
            FileInputStream is = null;
            try {
                is = new FileInputStream(code.image);
                bitmap = BitmapFactory.decodeFileDescriptor(is.getFD(), null, null);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return bitmap;
    }

    @Override
    public void handleDown(PointF pointF) {
        if (selectedCell == null) {
            // 先判断点击位置是否在frame内
            if (frameRectF.contains(pointF.x, pointF.y)) {
                // 再判断点击了哪个卡片
                for (int i = 0; i < optionCellList.size(); i++) {
                    Cell cell = optionCellList.get(i);
                    if (cell.rectF.contains(pointF.x, pointF.y)) {
                        selectedStartTime = System.currentTimeMillis();
                        cell.selected = true;
                        selectedCell = cell;
                        break;
                    }
                }
            }
        }

        if (trainingFinished) {
            if (leftBtnRectF.contains(pointF.x, pointF.y)) {
                activity.backToLastScene();
            } else if (rightBtnRectF.contains(pointF.x, pointF.y)) {
                restart = true;
                showNext = true;
                trainingFinished = false;

            }
        }
    }

    @Override
    public void handleUp(PointF pointF) {
        super.handleUp(pointF);
    }
}
